package com.tong.embeddedvr.service.impl;

import com.tong.embeddedvr.Mapper.HostMapper;
import com.tong.embeddedvr.Mapper.HostAccountMapper;
import com.tong.embeddedvr.constant.ConstantPool;
import com.tong.embeddedvr.dto.HostAccountDTO;
import com.tong.embeddedvr.dto.HostDTO;
import com.tong.embeddedvr.dto.UserOutputDTO;
import com.tong.embeddedvr.dto.vo.HostInfoVO;
import com.tong.embeddedvr.entity.HostAccountEntity;
import com.tong.embeddedvr.entity.HostEntity;
import com.tong.embeddedvr.entity.UserEntity;
import com.tong.embeddedvr.service.HostAccountService;
import com.tong.embeddedvr.timer.ShellTimer;
import com.tong.embeddedvr.utils.CommonUtil;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.omg.CORBA.COMM_FAILURE;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Timer;

@Service
public class HostAccountServiceImpl implements HostAccountService {
    @Autowired
    private HostAccountMapper hostAccountMapper;

    @Autowired
    private HostMapper hostMapper;

    @Autowired
    private HostServiceImpl hostService;

    @Autowired
    private SSHServiceImpl sshService;

    private final Logger logger = LoggerFactory.getLogger(HostAccountService.class);
    private final DefaultMapperFactory mapperFactory = CommonUtil.getMapperFactory();

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String allocateHostAccount(HttpSession session) throws Exception {
        String res = null;
        Long interval = null;
        HostAccountDTO hostAccountDTO = (HostAccountDTO) session.getAttribute(ConstantPool.HOST_ACCOUNT);
        HostDTO hostDTO = (HostDTO) session.getAttribute(ConstantPool.HOST);
        UserOutputDTO user = (UserOutputDTO) session.getAttribute(ConstantPool.USER);
        //如果session中有且未超过时限就直接交付
        //其实时间就是用date.getTime做数学计算
        if(hostAccountDTO!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date startTime = sdf.parse(hostAccountDTO.getHostAccountStartUseTime());
            interval = new Date().getTime() - startTime.getTime();
        }
        if(hostAccountDTO!=null&&hostDTO!=null&&interval<ShellTimer.DELAY_TIME){
            res = CommonUtil.ajaxReturn(new HostInfoVO(hostDTO.getHostIp(),22,hostAccountDTO.getHostAccountUsername(),hostAccountDTO.getHostAccountPassword()));
        }else{
            //如果在数据库中就有主机,直接获得
            if(user!=null){
                HostAccountEntity hostAccountProp = new HostAccountEntity();
                hostAccountProp.setUserId(user.getUserId());
                hostAccountDTO = hostAccountMapper.getHostAcountByUserId(hostAccountProp);
                if(hostAccountDTO!=null){
                    HostEntity hostProp = new HostEntity();
                    hostProp.setHostId(hostAccountDTO.getHostId());
                    hostDTO = hostMapper.getHostById(hostProp);
                    res = CommonUtil.ajaxReturn(new HostInfoVO(hostDTO.getHostIp(),22,hostAccountDTO.getHostAccountUsername(),hostAccountDTO.getHostAccountPassword()));
                }else{  //创建新的主机账号
                    HostDTO[] allHost = hostMapper.getAllHost();
                    int minn=HostDTO.MAX_USER_NUM;
                    HostDTO host=null;
                    for (HostDTO temp : allHost) {
                        System.out.println(temp);
                        if(temp.getHostUsernum()<minn){
                            minn = temp.getHostUsernum();
                            host = temp;
                        }
                    }
                    if(host==null){
                        res = CommonUtil.ajaxReturn(400,"当前用户已达上限!");
                    }else {
                        hostAccountDTO = new HostAccountDTO();
                        hostAccountDTO.setHostAccountIsDelete(0);
                        hostAccountDTO.setHostAccountStartUseTime(CommonUtil.getTime());
                        hostAccountDTO.setUserId(user.getUserId());
                        hostAccountDTO.setHostAccountState(1);
                        String username = CommonUtil.getRandomString(8);
                        String password = CommonUtil.getRandomString(8);
                        hostAccountDTO.setHostAccountUsername(username);
                        hostAccountDTO.setHostAccountPassword(password);
                        hostAccountDTO.setHostId(host.getHostId());
                        try {
                            sshService.useradd(host, hostAccountDTO);
                            DefaultMapperFactory mapperFactory = CommonUtil.getMapperFactory();
                        } catch (Exception e) {
                            throw e;
                        }
                        HostAccountEntity prop = mapperFactory.getMapperFacade().map(hostAccountDTO, HostAccountEntity.class);
                        hostAccountMapper.addHostAccount(prop);
                        hostAccountDTO = hostAccountMapper.getHostAcountByUserId(prop);
                        //更新host_usernum个数
                        HostEntity hostProp = mapperFactory.getMapperFacade().map(host, HostEntity.class);
                        hostMapper.increaseUseNum(hostProp);
                        host = hostMapper.getHostById(hostProp);
                        //设置定时器
                        delHostAccount(host,hostAccountDTO);
                        //设置返回值
                        HostInfoVO hostInfoVO = new HostInfoVO(host.getHostIp(),22,hostAccountDTO.getHostAccountUsername(),hostAccountDTO.getHostAccountPassword());
                        res = CommonUtil.ajaxReturn(hostInfoVO);
                        //在session中存储host和hostAccount
                        session.setAttribute(ConstantPool.HOST,host);
                        session.setAttribute(ConstantPool.HOST_ACCOUNT,hostAccountDTO);
                    }
                }
            }
        }
        return res;
    }

    @Override
    public String updateInformation(HostAccountDTO hostAccountDTO) {
        String res;
        HostAccountEntity prop = mapperFactory.getMapperFacade().map(hostAccountDTO, HostAccountEntity.class);
        try{
            hostAccountMapper.updateInformation(prop);
            res = CommonUtil.ajaxReturn("更新成功");
        }catch (Exception e){
            logger.error("更新主机信息失败|相关信息:[{}]",prop);
            e.printStackTrace();
            res = CommonUtil.ajaxReturn(400,"更新失败,请确认数据无误");
        }
        return res;
    }

    @Override
    public String getAllHostAccount() {
        String res;
        try{
            ArrayList<HostAccountDTO> allHostAccount = hostAccountMapper.getAllHostAccount();
            res = CommonUtil.ajaxReturn(allHostAccount);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("获取所有主机用户失败");
            res = CommonUtil.ajaxReturn(400,"更新失败,请确认数据无误");
        }
        return res;
    }

    //由一个定时器实现
    public void delHostAccount(HostDTO host, HostAccountDTO hostAccount) {
        try{
            Timer timer = new Timer();
            try {
                ShellTimer shellTimer = new ShellTimer();
                shellTimer.setSshService(sshService);
                shellTimer.setHostAccount(hostAccount);
                shellTimer.setHost(host);
                shellTimer.setHostAccountMapper(hostAccountMapper);
                shellTimer.setHostMapper(hostMapper);
                timer.schedule(shellTimer,shellTimer.DELAY_TIME);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }catch (Exception e){
            logger.error("定时器创建失败");
            logger.error("错误信息:[{}]",e.getMessage());
        }
    }

}
